/*
============================================================================
Name        : PopMenu.cpp
Author      : WB
Version     :
Copyright   : 
Description : CPopMenu implementation
============================================================================
*/

#include "PopMenu.h"
#include "BaseCommon.h"
#include "Block.h"
#include "eStockappui.h"
#include <stringloader.h>
#include "eStockDef.h"
#include "Toolbar.h"

const TInt m_nMenuMargin = 5;
const TInt m_nMenuSpaceRight = 25;
const TInt m_nMenuTotalSpace = m_nMenuMargin+m_nMenuSpaceRight;

CPopMenu::CPopMenu()
{
}

CPopMenu::~CPopMenu()
{
	m_subMenu.ResetAndDestroy();
}

CPopMenu* CPopMenu::NewL(const TInt& aId,const TInt& aResId)
{
	TBuf<16> tempBuf;
	StringLoader::Load(tempBuf,aResId);
	return CPopMenu::NewL(aId,tempBuf);
}

CPopMenu* CPopMenu::NewLC(const TInt& aId,const TDesC& aText)
{
	CPopMenu* self = new (ELeave)CPopMenu();
	CleanupStack::PushL(self);
	self->ConstructL(aId,aText);
	return self;
}

CPopMenu* CPopMenu::NewL(const TInt& aId,const TDesC& aText)
{
	CPopMenu* self=CPopMenu::NewLC(aId,aText);
	CleanupStack::Pop(); // self;
	return self;
}

void CPopMenu::ConstructL(const TInt& aId,const TDesC& aText)
{
	m_nId = aId;
	m_strText.Copy(aText);

	m_pMenuParent = NULL;
	m_menuListener = NULL;

	m_bIsPop = EFalse;
	m_nMaxWidth = 0;

	m_nAtvIndex = 0;
	m_nBgIndex = 0;
	m_bScroll = EFalse;

	m_nLines = 0;

	m_bRepaintAll = EFalse;

	m_bUpArrawPressed = EFalse;
	m_bDownArrawPressed = EFalse;
}

void CPopMenu::SetPopup(TBool aBool)
{
	if(m_subMenu.Count() > 0)
	{
		m_bIsPop = aBool; 
		if (m_bIsPop)
		{
			BASECOMMON->iToolbar->SetSoftKey(CToolbar::EOK, CToolbar::ECancel);
		}
		if(m_menuListener != NULL)
			m_menuListener->DynInitMenu();
	}
}

TBool CPopMenu::IsPopup()
{
	return m_bIsPop;
}

void CPopMenu::OnSize(TInt aPosX, TInt aPosY, TPopupMenuPosition aPosition)
{
	m_nMaxWidth = BASECOMMON->m_nScreenWidth/3;

	for(TInt i=0; i<m_subMenu.Count(); i++)
	{
		CPopMenu* menuItem = (CPopMenu*)m_subMenu[i];
		TInt w = CGlobal::Static()->g_font->TextWidthInPixels(menuItem->m_strText);
		if(w > m_nMaxWidth)
			m_nMaxWidth = w;
	}
	TInt width = m_nMaxWidth + m_nMenuTotalSpace;
	TInt height = m_subMenu.Count()*BASECOMMON->m_nLineHeight;

	if(m_pMenuParent == NULL)
	{ 
		switch (aPosition)
		{
		case TOPLEFT:
			{
				m_RectMenu.iTl.iX = aPosX;
				m_RectMenu.iBr.iY = aPosY + height;
				m_RectMenu.iTl.iY = aPosY;
				m_RectMenu.iBr.iX = aPosX + width;
				if(m_RectMenu.iBr.iY >= BASECOMMON->m_nScreenHeight - KCbabarHeight - KScrollInfobarHeight)
				{
					m_RectMenu.iTl.iY += BASECOMMON->m_nLineHeight;
					m_RectMenu.iBr.iY = BASECOMMON->m_nScreenHeight - KCbabarHeight - KScrollInfobarHeight - 1 - BASECOMMON->m_nLineHeight;
					m_bScroll = ETrue;
				}
			}
			break;
		case TOPRIGHT:
			{
				m_RectMenu.iTl.iX = aPosX - width;
				m_RectMenu.iBr.iY = aPosY + height;
				m_RectMenu.iTl.iY = aPosY;
				m_RectMenu.iBr.iX = aPosX;
				if(m_RectMenu.iBr.iY >= BASECOMMON->m_nScreenHeight - KCbabarHeight - KScrollInfobarHeight)
				{
					m_RectMenu.iTl.iY += BASECOMMON->m_nLineHeight;
					m_RectMenu.iBr.iY = BASECOMMON->m_nScreenHeight - KCbabarHeight - KScrollInfobarHeight - 1 - BASECOMMON->m_nLineHeight;
					m_bScroll = ETrue;
				}
			}
			break;
		case BOTTOMLEFT:
			{
				m_RectMenu.iTl.iX = aPosX;
				m_RectMenu.iBr.iY = aPosY;
				m_RectMenu.iTl.iY = aPosY - height;
				m_RectMenu.iBr.iX = aPosX + width;
				if(m_RectMenu.iTl.iY <= KTitlebarHeight + KTabbarHeight)
				{
					m_RectMenu.iBr.iY -= BASECOMMON->m_nLineHeight;
					m_RectMenu.iTl.iY = KTitlebarHeight + KTabbarHeight + 1 + BASECOMMON->m_nLineHeight;
					m_bScroll = ETrue;
				}
			}
			break;
		case BOTTOMRIGHT:
			{
				m_RectMenu.iTl.iX = aPosX + width;
				m_RectMenu.iBr.iY = aPosY;
				m_RectMenu.iTl.iY = aPosY - height;
				m_RectMenu.iBr.iX = aPosX;
				if(m_RectMenu.iTl.iY <= KTitlebarHeight + KTabbarHeight)
				{
					m_RectMenu.iBr.iY -= BASECOMMON->m_nLineHeight;
					m_RectMenu.iTl.iY = KTitlebarHeight + KTabbarHeight + 1 + BASECOMMON->m_nLineHeight;
					m_bScroll = ETrue;
				}
			}
			break;
		default:
			break;
		}
		if(IsPopup())
		{
			for(TInt i=0; i<m_subMenu.Count(); i++)
			{
				CPopMenu* menuItem = (CPopMenu*)m_subMenu[i];
				menuItem->OnSize();
			}
			m_bRepaintAll = ETrue;
		}
	}
	else
	{	
		m_RectMenu.iTl.iX = m_pMenuParent->m_RectMenu.iBr.iX+1;
		if(m_RectMenu.iTl.iX + width > BASECOMMON->m_nScreenWidth)
			m_RectMenu.iTl.iX = BASECOMMON->m_nScreenWidth - width;
		m_RectMenu.iBr.iX = m_RectMenu.iTl.iX + width-1;

		TInt index = m_pMenuParent->m_nAtvIndex - m_pMenuParent->m_nBgIndex;
		m_RectMenu.iTl.iY =  m_pMenuParent->m_RectMenu.iTl.iY + index*BASECOMMON->m_nLineHeight;
		m_RectMenu.iBr.iY = m_RectMenu.iTl.iY + height;
		if(m_RectMenu.iTl.iY + height > m_pMenuParent->m_RectMenu.iBr.iY )
		{
			m_RectMenu.iBr.iY = m_pMenuParent->m_RectMenu.iBr.iY;
			m_RectMenu.iTl.iY = m_RectMenu.iBr.iY-height;
			if(m_RectMenu.iTl.iY <= KTitlebarHeight + KTabbarHeight)
			{
				m_RectMenu.iBr.iY -= BASECOMMON->m_nLineHeight;
				m_RectMenu.iTl.iY = KTitlebarHeight + KTabbarHeight + 1 + BASECOMMON->m_nLineHeight;
				m_bScroll = ETrue;
			}
		}
		
//		m_RectMenu.iBr.iY = aPosY;
//		m_RectMenu.iTl.iY = aPosY - height;
//		if(m_RectMenu.iTl.iY <= KTitlebarHeight + KTabbarHeight)
//		{
//			m_RectMenu.iBr.iY -= BASECOMMON->m_nLineHeight;
//			m_RectMenu.iTl.iY = KTitlebarHeight + KTabbarHeight + 1 + BASECOMMON->m_nLineHeight;
//			m_bScroll = ETrue;
//		}
	}

	m_nLines = (m_RectMenu.iBr.iY - m_RectMenu.iTl.iY)/BASECOMMON->m_nLineHeight;

	m_Rect.iTl.iX = m_RectMenu.iTl.iX;
	m_Rect.iBr.iX = m_RectMenu.iBr.iX;
	m_Rect.iTl.iY = m_RectMenu.iTl.iY-2;
	m_Rect.iBr.iY = m_RectMenu.iBr.iY;

	if(m_bScroll)
	{
		m_RectUpArrow.iTl.iX = m_RectDownArrow.iTl.iX  = m_RectMenu.iTl.iX;
		m_RectUpArrow.iBr.iX = m_RectDownArrow.iBr.iX = m_RectMenu.iBr.iX;

		m_RectUpArrow.iTl.iY = (m_RectMenu.iTl.iY - BASECOMMON->m_nLineHeight)+2;
		m_RectUpArrow.iBr.iY = m_RectMenu.iTl.iY;

		m_RectDownArrow.iTl.iY = m_RectMenu.iBr.iY;
		m_RectDownArrow.iBr.iY = (m_RectMenu.iBr.iY + BASECOMMON->m_nLineHeight)-2;

		m_Rect.iTl.iX = m_RectUpArrow.iTl.iX;
		m_Rect.iBr.iX = m_RectDownArrow.iBr.iX;
		m_Rect.iTl.iY = m_RectUpArrow.iTl.iY;
		m_Rect.iBr.iY = m_RectDownArrow.iBr.iY;
	}
}

void CPopMenu::Append(CPopMenu* menuItem)
{
	if(menuItem != NULL)
	{
		menuItem->SetParent(this);
		m_subMenu.Append(menuItem);
	}
}


void CPopMenu::ChangeMenuItem(TInt id,TInt newId,const TDesC& newTxt)
{
	for(TInt i=0; i<m_subMenu.Count(); i++)
	{
		CPopMenu* popmenu = (CPopMenu*)m_subMenu[i];
		if(popmenu->m_nId == id)
		{
			popmenu->m_nId = newId;
			popmenu->m_strText.Copy(newTxt);
		}
	}
}

void CPopMenu::DrawSubMenu(CFbsBitGc& g)const
{
	TInt nX = m_RectMenu.iTl.iX+m_nMenuMargin;
	TInt nY = m_RectMenu.iTl.iY;
	//TInt w = m_nMaxWidth + m_nMenuTotalSpace;
	TInt w = m_Rect.Width();
	CGlobal* globe = CGlobal::Static();

	g.SetBrushStyle(CGraphicsContext::ESolidBrush);
	g.SetPenStyle(CGraphicsContext::ESolidPen);
	g.SetBrushColor(globe->g_rgbMenuBg);
	g.SetPenColor(globe->g_rgbText);
	g.DrawRoundRect(m_Rect,TSize(2,2));

	if(m_bScroll)
		DrawArrowButton(g);

	g.UseFont(globe->g_font);

	for(TInt i=0; i<m_nLines; i++)
	{
		TInt index = m_nBgIndex + i;

		if(m_nAtvIndex == index)
		{
//			CBaseBlock::DrawImageRect(g,TRect(TPoint(m_RectMenu.iTl.iX+2,nY),TSize(w-4,BASECOMMON->m_nLineHeight-1)),1);
            g.SetBrushColor(KRgbHighlight);
            g.SetBrushStyle(CGraphicsContext::ESolidBrush);
            g.SetPenStyle(CGraphicsContext::ENullPen);
            g.DrawRect(TRect(TPoint(m_RectMenu.iTl.iX+2,nY),TSize(w-4,BASECOMMON->m_nLineHeight-1)));
    
//			g.SetPenColor(globe->g_rgbHighlight);
            g.SetPenStyle(CGraphicsContext::ESolidPen);
		}
		else
		{
			g.SetPenColor(globe->g_rgbText);
		}
		CPopMenu* item = (CPopMenu*)m_subMenu[index];
		g.DrawText(item->m_strText,TPoint(nX,nY+globe->m_nSpaceUp+globe->g_nFontHeight));

		if(item->m_subMenu.Count() > 0)
		{
			TInt height = BASECOMMON->m_nLineHeight/4;
			TInt ptRx = m_RectMenu.iBr.iX-m_nMenuMargin;
			TInt ptRy = nY + height*2;

			g.SetBrushColor(globe->g_rgbMemo);
			TPoint ptArr1[3] = {TPoint(ptRx,ptRy),TPoint(ptRx-height,ptRy-height), TPoint( ptRx-height,ptRy+height)};
			g.DrawPolygon(ptArr1, 3);
		}

		nY += BASECOMMON->m_nLineHeight;
	}
}

void CPopMenu::OnDraw(CFbsBitGc& g)const
{

	if(!m_bIsPop)
		return;
	DrawSubMenu(g);

	CPopMenu* item = (CPopMenu*)m_subMenu[m_nAtvIndex];
	item->OnDraw(g);
}


void CPopMenu::DrawArrowButton(CFbsBitGc& g)const
{
	CGlobal* globe = CGlobal::Static();
	TRect rect(m_RectUpArrow);
	rect.Shrink(TSize(2,2));


	TInt h = rect.Height()/2;
	TInt w = h;

	//g.SetBrushColor(globe->g_rgbMemo);
	CBaseBlock::DrawImageRect(g,rect,2);

	//CGlobal::Draw3DRect(g,rect,m_bUpArrawPressed);

	TInt ptx = rect.iTl.iX +(rect.iBr.iX-rect.iTl.iX)/2;
	TInt pty = rect.iTl.iY + h/2;


	if(m_nBgIndex > 0)
		g.SetBrushColor(globe->g_rgbBackGround);
	else
		g.SetBrushColor(globe->g_rgbText);

	TPoint ptArr1[3] = {TPoint(ptx,pty),TPoint(ptx-w,pty+h), TPoint( ptx+w,pty+h)};
	g.DrawPolygon(ptArr1, 3);


	rect = m_RectDownArrow;
	rect.Shrink(TSize(2,2));
	//g.SetBrushColor(globe->g_rgbMemo);
	CBaseBlock::DrawImageRect(g,rect,2);

	//CGlobal::Draw3DRect(g,rect,m_bDownArrawPressed);
	pty = rect.iBr.iY - h/2;

	g.SetBrushColor(globe->g_rgbText);

	if(m_nBgIndex+m_nLines < m_subMenu.Count())
		g.SetBrushColor(globe->g_rgbBackGround);
	else
		g.SetBrushColor(globe->g_rgbText);

	TPoint ptArr2[3] = {TPoint(ptx,pty),TPoint(ptx-w,pty-h), TPoint( ptx+w,pty-h)};
	g.DrawPolygon(ptArr2, 3);

}

TBool CPopMenu::OnKeyDown(TInt keyCode)
{
	CGlobal* globe = CGlobal::Static();
	CPopMenu* curMenu = (CPopMenu*)m_subMenu[m_nAtvIndex];

	m_bRepaintAll = EFalse;

	if(curMenu->IsPopup())
	{
		return curMenu->OnKeyDown(keyCode);
	}
	else if(keyCode == globe->g_nKeyUp)
	{
		m_nAtvIndex--;
		if(m_nAtvIndex < 0)
		{
			m_nAtvIndex = m_subMenu.Count()-1;
			m_nBgIndex = m_nAtvIndex-m_nLines+1;
		}
		if(m_nAtvIndex == m_nBgIndex-1)
			m_nBgIndex --;

		return ETrue;
	}
	else if(keyCode == globe->g_nKeyDown)
	{
		m_nAtvIndex++;
		if(m_nAtvIndex >= m_subMenu.Count())
		{
			m_nAtvIndex = 0;
			m_nBgIndex = 0;
		}
		if(m_nAtvIndex-m_nBgIndex >= m_nLines)
			m_nBgIndex++;

		return ETrue;
	}
	else if(keyCode ==  globe->g_nKeyLeft || keyCode == globe->g_nKeyCancel)
	{
		if(m_bIsPop)
		{
			m_bIsPop = EFalse;
			m_bRepaintAll = ETrue;
			if(m_pMenuParent != NULL)
				m_pMenuParent->m_bRepaintAll = ETrue;
			else
				BASECOMMON->iToolbar->SetSoftKey(CToolbar::EMenu, CToolbar::EBack);
			return ETrue;
		}
	}
	else if(keyCode == globe->g_nKeyRight)
	{
		if(!curMenu->IsPopup() && curMenu->m_subMenu.Count()>0)
		{
			curMenu->m_bIsPop = ETrue;
			curMenu->OnSize();
			return ETrue;
		}
	}
	else if(keyCode == globe->g_nKeyOK || keyCode == globe->g_nKeySelect || keyCode == EStdKeyNkpAsterisk || keyCode=='*')
	{
		if( curMenu->m_subMenu.Count()>0)
		{
			if(!curMenu->IsPopup())
			{
				curMenu->m_bIsPop = ETrue;
				curMenu->OnSize();
				return ETrue;
			}
		}
		else
		{
			m_bIsPop = EFalse;
			BASECOMMON->iToolbar->SetSoftKey(CToolbar::EMenu, CToolbar::EBack);
			if(m_menuListener != NULL)
				return m_menuListener->OnMenuEvent(curMenu->m_nId);
			else if(m_pMenuParent->m_menuListener != NULL)
			{
				m_pMenuParent->m_bIsPop = EFalse;
				return m_pMenuParent->m_menuListener->OnMenuEvent(curMenu->m_nId);
			}
		}
	}
	return EFalse;
}

void CPopMenu::GetMenuText(const TInt& id,TDes& aText)
{
	for(TInt i=0; i<m_subMenu.Count(); i++)
	{
		CPopMenu* menuItem = m_subMenu[i];
		if(menuItem->m_nId == id)
		{
			aText.Copy(menuItem->m_strText);
			break;
		}
	}
}


TBool CPopMenu::OnMouseUp(const TPoint& aPt)
{
	CPopMenu* curMenu = (CPopMenu*)m_subMenu[m_nAtvIndex];
	if(curMenu->m_bIsPop && curMenu->m_Rect.Contains(aPt))
	{
		return curMenu->OnMouseUp(aPt);
	}

	if (m_RectMenu.Contains(aPt))
	{
		TRect rect;
		rect.iTl.iX = m_RectMenu.iTl.iX+2;
		rect.iBr.iX = m_RectMenu.iBr.iX-2;

		for(TInt i=0; i<m_nLines; i++)
		{
			TInt index = m_nBgIndex + i;

			rect.iTl.iY = m_RectMenu.iTl.iY+i*CBaseCommon::Static()->m_nLineHeight;
			rect.iBr.iY = rect.iTl.iY+CBaseCommon::Static()->m_nLineHeight;

			if(rect.Contains(aPt))
			{
				if(m_nAtvIndex == index)
				{
					CPopMenu* menu = (CPopMenu*)m_subMenu[index];
					if(menu->m_bIsPop)
						OnKeyDown(CGlobal::Static()->g_nKeyLeft);
					else
						OnKeyDown(CGlobal::Static()->g_nKeyOK);
					return ETrue;
				}
				else
				{
					return EFalse;
				}
			}
		}
	}

	if( m_bUpArrawPressed ||m_bDownArrawPressed )
	{
		m_bUpArrawPressed = EFalse;
		m_bDownArrawPressed = EFalse;
		return ETrue;
	}
	return EFalse;
}


TBool CPopMenu::OnMouseDown(const TPoint& aPt)
{
	CPopMenu* curMenu = (CPopMenu*)m_subMenu[m_nAtvIndex];
	if(curMenu->m_bIsPop && curMenu->m_Rect.Contains(aPt))
	{
		return curMenu->OnMouseDown(aPt);
	}

	if(m_Rect.Contains(aPt))
	{
		if (m_RectMenu.Contains(aPt))
		{
			TRect rect;
			rect.iTl.iX = m_RectMenu.iTl.iX+2;
			rect.iBr.iX = m_RectMenu.iBr.iX-2;

			for (TInt i = 0; i<m_nLines; i++)
			{
				TInt index = m_nBgIndex+i;
				rect.iTl.iY = m_RectMenu.iTl.iY+i*CBaseCommon::Static()->m_nLineHeight;
				rect.iBr.iY = rect.iTl.iY+CBaseCommon::Static()->m_nLineHeight;

				if (rect.Contains(aPt))
				{
					if(m_nAtvIndex != index)
					{
						CPopMenu* menu = (CPopMenu*)m_subMenu[m_nAtvIndex];
						menu->m_bIsPop = EFalse;
						m_bRepaintAll = ETrue;
					}
					m_nAtvIndex = index;
					return ETrue;
				}
			}
		}
		else if (m_bScroll)
		{
			if (m_RectUpArrow.Contains(aPt))
			{
				m_bUpArrawPressed = ETrue;
				CPopMenu* menu = (CPopMenu*)m_subMenu[m_nAtvIndex];
				if(menu->m_bIsPop)
					menu->m_bIsPop = EFalse;
				OnKeyDown(CGlobal::Static()->g_nKeyUp);
				m_bRepaintAll = ETrue;
				return ETrue;
			}
			else if (m_RectDownArrow.Contains(aPt))
			{
				m_bDownArrawPressed = ETrue;
				CPopMenu* menu = (CPopMenu*)m_subMenu[m_nAtvIndex];
				if(menu->m_bIsPop)
					menu->m_bIsPop = EFalse;

				OnKeyDown(CGlobal::Static()->g_nKeyDown);
				m_bRepaintAll = ETrue;
				return ETrue;
			}
		}
	}
	return EFalse;
}

void CPopMenu::SetAtvIndex(TInt n)
{
	m_nAtvIndex = n;
}
